from tablestore import *
import time

class TableUtil:
    def __init__(self, endpoint, instance_name, context):
        if endpoint is None or \
            instance_name is None or\
            context is None:
            raise RuntimeError('param has None')
        self.endpoint = endpoint
        self.instance_name = instance_name
        self.refresh_init(context)

    # 重新初始化
    def refresh_init(self, context):
        cred = context.credentials
        self.table_client = OTSClient(self.endpoint, cred.access_key_id, cred.access_key_secret, self.instance_name,
                                     sts_token=cred.security_token)

    # 获取实例下所有表的表名
    def get_table_list(self, context):
        if self.table_client is None:
            self.refresh_init(context)
        if self.table_client is not None:
            list_response = self.table_client.list_table()
            return list_response
        return None

    def put_row_dishInfo_noImg(self, context, primary_key, attribute_columns):
        '''
        插入一条菜品信息（无图），返回True/False 
        eg: primary_key = [('shopId', '商家A'), ('dishId', '')]
            attribute_columns = [('dishName', '爆炒土豆丝'), ('dishPrice', 1200), 
                                    ('dishTmpPrice', 1200), ('goodsType', 1=菜品/2=酒水)]
        '''
        if self.table_client is None:
            self.refresh_init(context)

        if self.table_client is not None: 
            table_name = 'dish_list'
            t = str(round(time.time()*1000))
            attribute_columns.append(('createTime', t))
            attribute_columns.append(('updateTime', t))
            row = Row(primary_key, attribute_columns)
            # consumed 表示消耗的CapacityUnit，是tablestore.metadata.CapacityUnit类的实例
            # return_row 表示返回的行数据，可能包括主键、属性列
            # return_type=ReturnType.RT_PK 返回主键列, eg: [('shopId', '商家A'), ('dishId', 1627371849355000)]
            # consumed, return_row = self.table_client.put_row(table_name, row, return_type=ReturnType.RT_PK)
            # return return_row.primary_key
            self.table_client.put_row(table_name, row)
            return True
        return False

    '''
    插入一条菜品信息，返回True/False 
    eg: primary_key = [('shopId', '商家A'), ('dishId', '')]
        attribute_columns = [('dishName', '爆炒土豆丝'), ('dishPrice', 1200), ('dishTmpPrice', 1200), ('goodsType', 1=菜品/2=酒水)]
    primary_key主键相同情况下多次调用，会覆盖之前的数据（更新操作）
    '''
    def put_row_dishInfo(self, context, primary_key, attribute_columns):
        if self.table_client is None:
            self.refresh_init(context)

        if self.table_client is not None: 
            table_name = 'dish_list'
            t = str(round(time.time()*1000))
            attribute_columns.append(('createTime', t))
            attribute_columns.append(('updateTime', t))
            row = Row(primary_key, attribute_columns)
            # consumed 表示消耗的CapacityUnit，是tablestore.metadata.CapacityUnit类的实例
            # return_row 表示返回的行数据，可能包括主键、属性列
            # return_type=ReturnType.RT_PK 返回主键列, eg: [('shopId', '商家A'), ('dishId', 1627371849355000)]
            # consumed, return_row = self.table_client.put_row(table_name, row, return_type=ReturnType.RT_PK)
            # return return_row.primary_key
            self.table_client.put_row(table_name, row)
            return True
        return False

    '''
    删除一条菜品信息，返回True/False 
    eg: primary_key = [('shopId', '商家A'), ('dishId', '')]
    '''
    def delete_row_dishInfo(self, context, primary_key):
        if self.table_client is None:
            self.refresh_init(context)

        if self.table_client is not None:
            table_name = 'dish_list'
            row = Row(primary_key)
            self.table_client.delete_row(table_name, row)
            return True
        return False

    '''
    插入一条菜品特征信息，返回True/False 
    eg: primary_key = [('shopId', '商家A'), ('feaId', ''), ('dishId', '')]
        attribute_columns = [('feaImgUrl', 'oss url')]
    '''
    def put_row_feaInfo(self, context, primary_key, attribute_columns):
        if self.table_client is None:
            self.refresh_init(context)

        if self.table_client is not None: 
            table_name = 'dish_fea_list'
            t = str(round(time.time()*1000))
            attribute_columns.append(('createTime', t))
            attribute_columns.append(('updateTime', t))
            row = Row(primary_key, attribute_columns)
            self.table_client.put_row(table_name, row)
            return True
        return False

    '''
    删除一条菜品特征信息，返回True/False 
    eg: primary_key = [('shopId', '商家A'), ('feaId', ''), ('dishId', '')]
    '''
    def delete_row_feaInfo(self, context, primary_key):
        if self.table_client is None:
            self.refresh_init(context)

        if self.table_client is not None:
            table_name = 'dish_fea_list'
            row = Row(primary_key)
            self.table_client.delete_row(table_name, row)
            return True
        return False

    '''
    插入一条菜单信息，返回True/False 
    eg: primary_key = [('shopId', '商家A'), ('taleId', '')]
        attribute_columns = [('taleName', '')]
    '''
    def put_row_menuInfo(self, context, primary_key, attribute_columns):
        if self.table_client is None:
            self.refresh_init(context)

        if self.table_client is not None: 
            table_name = 'dish_fea_list'
            primary_key.append('codeType', 'menulist')
            t = str(round(time.time()*1000))
            attribute_columns.append(('createTime', t))
            attribute_columns.append(('updateTime', t))
            row = Row(primary_key, attribute_columns)
            self.table_client.put_row(table_name, row)
            return True
        return False

    '''
    删除一条菜单信息，返回True/False 
    eg: primary_key = [('shopId', '商家A'), ('taleId', '')]
    '''
    def delete_row_menuInfo(self, context, primary_key):
        if self.table_client is None:
            self.refresh_init(context)

        if self.table_client is not None:
            table_name = 'dish_fea_list'
            primary_key.append('codeType', 'menulist')
            row = Row(primary_key)
            self.table_client.delete_row(table_name, row)
            return True
        return False

    '''
    插入一条菜品类别信息，返回True/False 
    eg: primary_key = [('shopId', '商家A'), ('taleId', '')]
        attribute_columns = [('taleName', '')]
    '''
    def put_row_classInfo(self, context, primary_key, attribute_columns):
        if self.table_client is None:
            self.refresh_init(context)

        if self.table_client is not None:
            table_name = 'dish_fea_list'
            primary_key.append('codeType', 'classlist')
            t = str(round(time.time()*1000))
            attribute_columns.append(('createTime', t))
            attribute_columns.append(('updateTime', t))
            row = Row(primary_key, attribute_columns)
            self.table_client.put_row(table_name, row)
            return True
        return False

    '''
    删除一条菜品类别信息，返回True/False 
    eg: primary_key = [('shopId', '商家A'), ('taleId', '')]
    '''
    def delete_row_classInfo(self, context, primary_key):
        if self.table_client is None:
            self.refresh_init(context)

        if self.table_client is not None:
            table_name = 'dish_fea_list'
            primary_key.append('codeType', 'classlist')
            row = Row(primary_key)
            self.table_client.delete_row(table_name, row)
            return True
        return False
             
    '''
    根据商家Id、dishId查询菜品详情信息
    return:
        { 
            'dishId': '',
            'dishName': '',
            'createTime': '1627740924956',
            'updateTime': '1627740924956',
            'dishPrice': 1200,
            'dishes': [
                {
                    'feaId': '', 
                    'feaImgUrl': 'oss url', 
                    'createTime': '1627740924969', 
                    'updateTime': '1627740924969'
                }
            ]
        }
    '''
    def get_dish_details(self, context, shopId, dishId):
        if self.table_client is None:
            self.refresh_init(context)

        if self.table_client is not None:
            primary_key = [('shopId', shopId), ('dishId', dishId)]
            columns_to_get = ['dishName', 'dishPrice', 'createTime', 'updateTime']
            _, return_row, _ = self.table_client.get_row('dish_list', primary_key, columns_to_get, None, 1)
            dishInfo = {'dishId': dishId, 'dishName': '', 'createTime': '', 'updateTime': '', 'dishes':[]}
            for x in return_row.attribute_columns:
                if x[0] == 'dishName':
                    dishInfo['dishName'] = x[1]
                if x[0] == 'dishPrice':
                    dishInfo['dishPrice'] = x[1]
                if x[0] == 'createTime':
                    dishInfo['createTime'] = x[1]
                if x[0] == 'updateTime':
                    dishInfo['updateTime'] = x[1]
            # 多条件组合查询
            bool_query = BoolQuery(
                must_queries = [
                    TermQuery('shopId', shopId),
                    TermQuery('dishId', dishId)
                ]
            )
            # 多元索引
            search_response = self.table_client.search('dish_fea_list', 'shopId_dishId_index', 
                SearchQuery(
                    bool_query,
                    limit=100,
                    get_total_count=True),
                ColumnsToGet(return_type=ColumnReturnType.ALL)
            )
            dishes = []
            for feas in search_response.rows:
                dish = {'feaId': '', 'feaImgUrl': '', 'createTime': '', 'updateTime': ''}
                for fea in feas:
                    for x in fea:
                        if x[0] == 'feaId':
                            dish['feaId'] = x[1]
                        if x[0] == 'feaImgUrl':
                            dish['feaImgUrl'] = x[1]
                        if x[0] == 'createTime':
                            dish['createTime'] = x[1]
                        if x[0] == 'updateTime':
                            dish['updateTime'] = x[1]
                dishes.append(dish)
            dishInfo['dishes'] = dishes
        return None, None

    '''
    匹配所有行查询
    '''
    def get_MatchAllQuery12(self, context, table_name, index_name, shopId='商家A'):
        if self.table_client is None:
            self.refresh_init(context)

        query = MatchPhraseQuery('shopId', shopId)
        if self.table_client is not None:
            all_rows, next_token = [], None
            while not all_rows or next_token:
                search_response = self.table_client.search(table_name, index_name,
                    SearchQuery(query, next_token=next_token, limit=100, get_total_count=True),
                    columns_to_get = ColumnsToGet(return_type=ColumnReturnType.ALL)
                )
                all_rows.extend(search_response.rows)
            for row in all_rows:
                print('row=====', row)
            return all_rows
        return None

    def get_rowList(self, context, table_name, index_name, query):
        if self.table_client is None:
            self.refresh_init(context)
        
        if self.table_client is not None:
            all_rows, next_token = [], None
            while not all_rows or next_token:
                rows, next_token, total_count, is_all_succeed = self.table_client.search(
                    table_name, index_name,
                    SearchQuery(query, limit=100, get_total_count=True),
                    ColumnsToGet(return_type=ColumnReturnType.ALL)
                )
                all_rows.extend(rows)
            return all_rows
        return None

    def test_exist_dish_list_dishName(self):
        # 多条件组合查询
        bool_query = BoolQuery(
            must_queries = [
                TermQuery('shopId', '商家A'),
                TermQuery('dishName', '哈密瓜')
            ]
        )
        # 多元索引
        search_response = self.table_client.search('dish_list', 'shopId_dishName_index', 
            SearchQuery(bool_query, limit=100, get_total_count=True),
            ColumnsToGet()
        )
        if search_response.total_count > 0:
            print('大于0-----', type(search_response))
        print('===', len(search_response.rows), '-=-=', search_response.total_count)
        print('----------------------------------------')
        print(search_response.rows)
        # for feas in search_response.rows:
        #     print('----------', feas)


